﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;

namespace Tools
{
        /// <summary>
        /// Represents an <see cref="ICommand"/> which runs an event handler when it is invoked.
        /// </summary>
        public class DelegateCommand : ICommand
        {
            private readonly Action<object> _executeAction;
            private readonly Predicate<object> _canExecute;

            /// <summary>
            /// Raised when changes occur that affect whether or not the command should execute.
            /// </summary>
            /// <remarks>
            /// The trick to integrate into WPF command manager found on: 
            /// http://joshsmithonwpf.wordpress.com/2008/06/17/allowing-commandmanager-to-query-your-icommand-objects/
            /// </remarks>
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }

            /// <summary>
            /// Creates a new instance of <see cref="DelegateCommand"/> and assigns the given action to it.
            /// </summary>
            /// <param name="executeAction">Event handler to assign to the command.</param>
            public DelegateCommand(Action<object> executeAction)
                : this(executeAction, null)
            {
            }

            /// <summary>
            /// Creates a new instance of <see cref="DelegateCommand"/> and assigns the given action and predicate to it.
            /// </summary>
            /// <param name="executeAction">Event handler to assign to the command.</param>
            /// <param name="canExecute">Predicate to check whether the command can be executed.</param>
            public DelegateCommand(Action<object> executeAction, Predicate<object> canExecute)
            {
                _executeAction = executeAction;
                _canExecute = canExecute;
            }

            /// <summary>
            /// Defines the method that determines whether the command can execute in its current state.
            /// </summary>
            /// <returns>
            /// true if this command can be executed; otherwise, false.
            /// </returns>
            /// <param name="parameter">Data used by the command. If the command does not require data 
            /// to be passed, this object can be set to null.</param>
            public bool CanExecute(object parameter)
            {
                return _canExecute == null ? true : _canExecute.Invoke(parameter);
            }

            /// <summary>
            /// Defines the method to be called when the command is invoked. The method will invoke the
            /// attached event handler.
            /// </summary>
            /// <param name="parameter">Data used by the command. If the command does not require data 
            /// to be passed, this object can be set to null.</param>
            public void Execute(object parameter)
            {
                _executeAction.Invoke(parameter);
            }
        }
    }
